package cn.wizzer.app.crown.modules.services.impl.pl.ft;

import cn.wizzer.app.crown.commons.websocket.action.hg.ChampionAction;
import cn.wizzer.app.crown.modules.models.CrownLeague;
import cn.wizzer.app.crown.modules.models.CrownMatch;
import cn.wizzer.app.crown.modules.models.caches.CrownMatchChampion;
import cn.wizzer.app.crown.modules.models.constant.CrownConstant;
import cn.wizzer.app.crown.modules.models.constant.CrownPattern;
import cn.wizzer.app.crown.modules.models.constant.CrownRedisConstant;
import cn.wizzer.app.crown.modules.models.enums.MatchTypeEnum;
import cn.wizzer.app.crown.modules.models.enums.PlayWayEnum;
import cn.wizzer.app.crown.modules.services.CrownConfigService;
import cn.wizzer.app.crown.modules.services.CrownLeagueService;
import cn.wizzer.app.crown.modules.services.CrownMatchService;
import cn.wizzer.app.crown.modules.services.pl.ft.FsResolverService;
import cn.wizzer.app.crown.modules.models.CrownConfig;
import cn.wizzer.app.match.modules.models.constant.Fields;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.util.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nutz.dao.Dao;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

/**
 * 冠军玩法爬取
 */
@IocBean(args = {"refer:dao"})
@Service(interfaceClass = FsResolverService.class)
public class FsResolverServiceImpl extends BaseServiceImpl<CrownMatch> implements FsResolverService {

    public FsResolverServiceImpl(Dao dao) {
        super(dao);
    }

    private static final Log log = Logs.get();

    @Inject
    private RedisService redisService;
    @Inject
    private CrownMatchService matchService;
    @Inject
    private CrownLeagueService leagueService;
    @Inject
    @Reference(retries = 0, timeout = 500000)
    private CrownConfigService crownConfigService;

    @Override
    public void crawler(CrownConfig config) {
        new PageAction() {
            @Override
            public void handle(List<JSONArray> list) {
                // 最终打点再此处理
                String leagueKey = Fields.PREFIX_CROWN + MatchTypeEnum.FOOTBALL + Fields.KEY_JOIN + PlayWayEnum.FS + Fields.SUFFIX_LEAGUE;
                CrownMatchChampion champion = new CrownMatchChampion();
                list.forEach(data -> {
                    CrownLeague league = new CrownLeague();
                    league.setChampionId(data.getString(0));
                    // 冠军名称
                    league.setChampionName(data.getString(3));
                    // 类型
                    league.setType(MatchTypeEnum.FOOTBALL);
                    // 决赛时间
                    league.setDateTime(data.getDate(1));
                    // 联赛名称
                    league.setLeague(data.getString(2));
                    // 比赛状态
                    league.setStage(CrownConstant.RUNNING);

                    CrownLeague old = leagueService.queryByLeagueInfo(league.getType(), league.getLeague(),
                            league.getChampionName(), league.getDateTime());
                    if (old != null) {
                        league.setId(old.getId());
                    }
                    // 入库赛事
                    leagueService.insertOrUpdate(league);
                    // 存入redis并设置过期时间
                    redisService.setex(leagueKey + Fields.KEY_COLON + league.getId(),
                            CrownRedisConstant.TIME_OUT_180_S, JSONUtil.toJSONString(league));

                    // 具体玩法key：FS#LID:4bcd117fbbb04a05a21d36d61deb75be
                    String redisKey = CrownRedisConstant.CHAMPION + league.getId();
                    // 所属联赛
                    champion.setCoeWord(data.getString(2) + data.getString(3));
                    //set plays
                    String[] coes = champion.getCoeWord().split("-");
                    // 防止队伍数据重复插入
                    redisService.del(redisKey);
                    // 时间
                    champion.setTime(data.getDate(1));
                    for (int i = 0; i < (data.size() - 7) / 4; i++) {
                        // 联赛Id
                        champion.setLeagueId(league.getId());
                        // 队伍ID(目前没有用到。队伍id为了防止队伍名称发生变化)
                        champion.setTId(data.getString(i * 4 + 1 + 6));
                        // 队伍名称
                        champion.setTeam(data.getString(i * 4 + 2 + 6));
                        // 赔率
                        champion.setOdds(data.getBigDecimal(i * 4 + 3 + 6));
                        // websocket推送
                        ChampionAction.instance().push(champion.getLeagueId(), champion);
                        redisService.rpush(redisKey, JSONObject.toJSONString(champion));
                    }
                    //设置过期时间
                    redisService.expire(redisKey, CrownRedisConstant.TIME_OUT_180_S);
                });
            }
        }.page(config);
    }


    /**
     * 分页获取数据
     */
    public abstract class PageAction {

        // 处理每一页数据，只需要组装返回
        public abstract void handle(List<JSONArray> list);

        public void page(CrownConfig config) {
            log.info("准备请求爬取冠军玩法实时数据");
            String tailUrl = "/app/member/browse_FS/reloadgame_R.php?uid=" + config.getUid() + "&langx=" + CrownConstant.LANGX + "&choice=ALL&LegGame=ALL&pages=1&records=40&FStype=FT&area_id=&league_id=&rtype=fs&hot_game=";
            List<JSONArray> list = new ArrayList<>();
            String body = crownConfigService.getCrownData(tailUrl, config, CrownConstant.RE_TRY_TIMES);
            // 检测账号被登出
            if (crownConfigService.checkLogout(body, config)) {
                // 重试登录(包括重试三次、自动请求新地址)
//                crownConfigService.loginHg(config);
//                // 如果登录成功 重新请求数据
//                if (!config.isLogout()) {
//                    this.page(config);
//                    return;
//                }
                return;
            }
            // body是空，监测到皇冠维护都return
            if (Strings.isBlank(body)) {
                log.error("爬取足球冠军失败，body为空");
                return;
            } else if (crownConfigService.checkMaintain(body, config)) {
                return;
            }

            log.info("开始爬取足球冠军数据");
            body = body.replaceAll("Array\\(\\)", "");
            Matcher m = CrownPattern.CHAMPION_DATA_PATTERN.matcher(body);
            String fsData = null;
            while (m.find()) {
                fsData = m.group();
                fsData = "[" + fsData.substring(fsData.indexOf("(") + 1, fsData.lastIndexOf(")")) + "]";
                list.add(JSONArray.parseArray(fsData));
            }
            // 信息入库
            handle(list);
            log.info("（ft_fs）数据条数->total:" + list.size());
        }
    }
}